package com.hmjk.health.util;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import com.hmjk.health.HealthApp;
import com.hmjk.health.R;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCodeActivity extends Activity implements OnClickListener{
	private final String TAG = QRCodeActivity.class.getSimpleName();
	public final static String TYPE_APK = "share_app";
	public final static String TYPE_FAMILY = "family_invitation";
	public final static String TYPE_DEVICE = "interest_device";
	
	private final int QRWIDTH = 300;//pixels
	private final int QRHEIGHT = 300;
	private HealthApp mApp;
	private ImageView bar;
	private TextView version;
	private CreateQRCodeTask mQRTask;
	private String mUri;
	private int mMiddleLogoRes;
	private Bitmap mBitmap;
	private String mFilePath;
	private String mType;
	
	private void logd(String info){
		Log.d(TAG,info);
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		logd("onCreate");
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		mApp = (HealthApp)getApplication();

		mFilePath = mApp.getQRTempJpgFileName();
		Intent i = getIntent();
		mType = i.getStringExtra("type");
		mUri = i.getStringExtra("uri");
		if(i.hasExtra("mid"))
			mMiddleLogoRes = i.getIntExtra("mid", -1);
		else
			mMiddleLogoRes = -1;
		
		setContentView(R.layout.qrcode_share_activity);
		ImageButton back = (ImageButton) findViewById(R.id.back);
		back.setOnClickListener(this);
		ImageButton share = (ImageButton)findViewById(R.id.share);
		share.setOnClickListener(this);
		
		bar = (ImageView) findViewById(R.id.qrcodeview);
		TextView tips = (TextView) findViewById(R.id.tips);
		if(mType.equals(TYPE_FAMILY)){
			tips.setVisibility(View.VISIBLE);
			tips.setText("");
			try {
				int pos = mUri.indexOf("fname=");
				String fgbname = mUri.substring(pos+6);
				String decode = URLDecoder.decode(fgbname, "UTF-8");
				String show = getResources().getString(R.string.share_fa_tips, decode);
				tips.setText(show);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else if(mType.equals(TYPE_DEVICE)){
			tips.setVisibility(View.VISIBLE);
			tips.setText("");
			try {
				int pos = mUri.indexOf("dname=");
				String dgbname = mUri.substring(pos+6);
				String decode = URLDecoder.decode(dgbname, "UTF-8");
				String show = getResources().getString(R.string.share_dev_tips, decode);
				tips.setText(show);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		version = (TextView) findViewById(R.id.version);
		
		String pkName = getPackageName();
        String versionName = "unknown";
        try {
        	versionName = getPackageManager().getPackageInfo(pkName, 0).versionName;
			
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			versionName = "unknown";
		}
        
        version.setText(getResources().getString(R.string.version, versionName));
        releaseBitmap();
        clearTempFile();
	}
	
	@Override
	public void onResume(){
		super.onResume();
		if((mUri == null) || mUri.trim().isEmpty()){
			finish();
			return;
		}
		
		if((mFilePath == null) || mFilePath.trim().isEmpty()){
			finish();
			return;
		}
		
		if(mBitmap == null){
			mApp.showWaitting(this, new OnCancelListener(){
	
				@Override
				public void onCancel(DialogInterface arg0) {
					mQRTask.cancel(false);
					finish();
				}
				
			});
			mQRTask = new CreateQRCodeTask();
			mQRTask.execute();
		}
	}
	
	@Override
	public void onDestroy(){
		super.onDestroy();
		releaseBitmap();
		clearTempFile();
	}
	
	private void clearTempFile(){
		File f = new File(mFilePath);
		if(f.exists())
			f.delete();
	}
	
	private void releaseBitmap(){
		if(mBitmap != null){
			if(!mBitmap.isRecycled()){
				mBitmap.recycle();
				System.gc();
			}
		}
		mBitmap = null;
	}
	
	class CreateQRCodeTask extends AsyncTask<Void,Void,Boolean>{
		
		@Override
		protected void onCancelled(Boolean result){
			clearTempFile();
		}
    	
		@Override
		protected void onPostExecute(Boolean result){
			releaseBitmap();
			mApp.dismissWaiting();
			
			if(result){
				mBitmap = BitmapFactory.decodeFile(mFilePath);
				bar.setImageBitmap(mBitmap);
			}
		}
		
		@Override
		protected Boolean doInBackground(Void... arg0) {
			
			Bitmap qrBitmap = null;
			
			try {
				Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
				hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
				hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
				
				BitMatrix bitMatrix = new QRCodeWriter().encode(mUri, BarcodeFormat.QR_CODE, QRWIDTH, QRHEIGHT, hints);
				int[] pixels = new int[QRWIDTH * QRHEIGHT];
				
				for(int y = 0; y < QRHEIGHT; y++){
					for(int x = 0; x < QRWIDTH; x++){
						if(bitMatrix.get(x, y)){
							pixels[y * QRWIDTH + x] = 0xff000000;
						}else{
							pixels[y * QRWIDTH + x] = 0xffffffff;
						}
					}
				}
				
				Bitmap bitmap = Bitmap.createBitmap(QRWIDTH, QRHEIGHT, Bitmap.Config.ARGB_8888);
				bitmap.setPixels(pixels, 0, QRWIDTH, 0, 0, QRWIDTH, QRHEIGHT);
				
				qrBitmap = bitmap;
				if(mMiddleLogoRes > 0){
					Bitmap logo = BitmapFactory.decodeResource(getResources(), mMiddleLogoRes);
					qrBitmap = addLogo(bitmap, logo);
					logo.recycle();
					bitmap.recycle();
				}
				
				boolean ok = qrBitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(mFilePath));
				qrBitmap.recycle();
				System.gc();
				return ok;
				
			} catch (WriterException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				
			}
			if(qrBitmap != null){
				if(!qrBitmap.isRecycled())
					qrBitmap.recycle();
			}
			return false;
		}

		private Bitmap addLogo(Bitmap qr, Bitmap logo){
			int qrw = qr.getWidth();
			int qrh = qr.getHeight();
			int logw = logo.getWidth();
			int logh = logo.getHeight();
			
			float scale = qrw * 1.0f / 5 / logw;
			Bitmap bitmap = Bitmap.createBitmap(qrw, qrh, Bitmap.Config.ARGB_8888);
			try{
				Canvas canvas = new Canvas(bitmap);
				canvas.drawBitmap(qr, 0, 0, null);
				canvas.scale(scale, scale, qrw/2, qrh/2);
				canvas.drawBitmap(logo, (qrw - logw)/2, (qrh - logh)/2, null);
				canvas.save(Canvas.ALL_SAVE_FLAG);
				canvas.restore();
			}catch(Exception e){
				e.printStackTrace();
				if(!bitmap.isRecycled())
					bitmap.recycle();
				bitmap = null;
			}
			
			return bitmap;
		}
		
	}
	
	private void share() {
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.setType("image/*");
		Uri imageUri = Uri.parse("file://" + mFilePath);
		
		List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(intent, 0);
		if (!resInfo.isEmpty()) {
	        List<Intent> targetedShareIntents = new ArrayList<Intent>();
	        for (ResolveInfo info : resInfo) {    		
	            ActivityInfo activityInfo = info.activityInfo;
	        	String pname = activityInfo.packageName;
	        	String name = activityInfo.name;
	        	//Log.d(TAG, pname + ":"+name);
	        	if(name.contains("com.tencent.mm") || name.contains("bluetooth") || name.contains("mobileqq")){
	        		Intent targeted = new Intent(Intent.ACTION_SEND);
		            targeted.setType("image/*");
		            targeted.putExtra(Intent.EXTRA_STREAM, imageUri);
		            targeted.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		    		
	        		targeted.setPackage(pname);
	        		targeted.setClassName(pname, name);
	                targetedShareIntents.add(targeted);
	        	}
	        }
	        
	        Intent chooser = Intent.createChooser(targetedShareIntents.remove(0), getResources().getString(R.string.menu_share));
	        chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[] {}));
	        startActivity(chooser);
		}
	}
	

	@Override
	public void onClick(View v) {
		switch(v.getId()){
		case R.id.back:{
			finish();
		}break;
		case R.id.share:{
			share();
		}break;
		}
		
	}

}
